﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.ComponentModel;
using FinPlusInterfaces;
using FinPlusAssembler;
using FinPlusCompCore;

namespace FinPlusCompProxy
{
    public class Instrument
    {
        private enum Infos { Settle, End, Instrument, CurveName, SettlementDays, Maturity, Index, DayCount, BizConv, Holidays, Unknown }
        private enum Params { LevelUpdate, Refresh };

        private IPod _instrument, _instrumentBuild;
        private QLAnalytics _analytics;
        private BuildEvent _buildEvents;
        private IBean _timeStamp;
        private string _name;
        private int _settle, _end;

        public Instrument(string name, IPod instrument, IPod instrumentBuild, QLAnalytics analytics, BuildEvent buildEvents)
        {
            _name = name;
            _analytics = analytics;
            _instrument = instrument;
            _instrument.Add(_analytics.Infos);
            _instrument.Add(_analytics.Controls);
            _instrument.Get(Params.LevelUpdate.ToString(), IOC.New<IPod>(), Instrument_Update);

            if (buildEvents == BuildEvent.Refresh || buildEvents == BuildEvent.UpdateAndRefresh)
                _instrument.Get(Params.Refresh.ToString(), string.Empty, Instrument_Refresh);

            _timeStamp = _instrument.Get(PodField.TimeStamp.ToString());
            _instrumentBuild = instrumentBuild;
            _buildEvents = buildEvents;
            Info();
        }

        //private
        private void Info()
        {
            if (_instrumentBuild == null) return;

            lock (_analytics.QL)
            {
                _settle = _analytics.QL.NextBizDate(_analytics.AsOf, _instrumentBuild[Infos.SettlementDays.ToString()].ToString() + "D", Infos.BizConv.ToString(), false, _instrumentBuild[Infos.Holidays.ToString()].ToString());
                _end = _analytics.QL.NextBizDate(_settle, _instrumentBuild[Infos.Maturity.ToString()].ToString(), _instrumentBuild[Infos.BizConv.ToString()].ToString(), false, _instrumentBuild[Infos.Holidays.ToString()].ToString());
            }

            foreach (var kvp in _analytics.Infos)
            {
                var val = kvp.Key.EnumParse<Infos>(Infos.Unknown);
                switch (val)
                {
                    case Infos.Settle: _instrument.Get(Infos.Settle.ToString()).Update(_settle); break;
                    case Infos.End: _instrument.Get(Infos.End.ToString()).Update(_end); break;
                    case Infos.Unknown: _instrument.Get(Infos.Unknown.ToString()).Update(Infos.Unknown.ToString()); break;
                    default: _instrument.Get(val.ToString()).Update(_instrumentBuild[val.ToString()]); break;//build info
                }
            }
        }

        private void Value()
        {
            if (!_analytics.HasControlString) return;
        }

        //events
        private void Instrument_Update(object s, PropertyChangedEventArgs a)
        {
            try
            {
                if (_buildEvents != BuildEvent.Update && _buildEvents != BuildEvent.UpdateAndRefresh) return;

                Value();
            }
            catch (Exception e)
            {
                Level.Error.Log(e.Message, e);
            }
        }

        private void Instrument_Refresh(object s, PropertyChangedEventArgs a)
        {
            if (((IBean)s).ToString().Equals(_name))
                Value();
        }
    }
}
